﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Scheduling.Models.Helpers;
using System.IO;

namespace Scheduling.Models
{
    public class RestrictAttribute : System.Attribute
    {
        /// <summary>
        /// The Roles that are allowed to access the resources. Administrators and System Operators are allowed to access all parts of the system. 
        /// </summary>
        public string Roles { get; set; }

        /// <summary>
        /// Disallow Administrators from accessing this function
        /// </summary>
        public bool OnlySysOp { get; set; }
    }
    public class BaseController : Controller
    {
        /// <summary>
        /// Overrides the default authentication behaviour. Restrict access using the Restrict attribute. 
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            bool Authenticated = true;

            var attributes = filterContext.ActionDescriptor.GetCustomAttributes(false);
            var authList = attributes.Where(u => u.GetType() == typeof(RestrictAttribute));
            if (authList.Count() > 0)
            {
                var auth = authList.First() as RestrictAttribute;

                if (!string.IsNullOrEmpty(SessionManager.UserID))
                {
                    if (SessionManager.UserGroupName == "Administrators" || SessionManager.UserGroupName == "System Operators")
                    {
                        Authenticated = true;
                        if (auth.OnlySysOp && SessionManager.UserGroupName == "Administrators")
                            Authenticated = false;
                    }
                    else if (string.IsNullOrWhiteSpace(auth.Roles))
                    {
                        Authenticated = false;
                    }
                    else
                    {
                        var roles = auth.Roles.Split(',');
                        if (!roles.Contains(SessionManager.UserGroupName))
                            Authenticated = false;
                    }
                }
                else
                    Authenticated = false;
            }

            if (!Authenticated)
                AccessDenied();
        }

        protected string FileNotFound()
        {
            Response.Clear();
            Response.Write(RenderPartialViewToString("Error", "404"));
            Response.End();
            return "";
        }

        protected string AccessDenied()
        {
            Response.Clear();
            Response.Write(RenderPartialViewToString("Error", "403"));
            Response.End();
            return "";
        }

        protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

    }
}